<?php
/**
 * Created by PhpStorm.
 * User: chentairen
 * Date: 2017/11/16
 * Time: 上午10:49
 */

namespace App\Service;

use App\Common\Model\ShopAccount;
use App\Model\Btree;
use App\Model\Pay;
use App\Model\Setting;
use App\Traits\ErrorTrait;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use PHPUnit\Runner\Exception;


class PointsService
{
    use ErrorTrait;

    /**
     * 获取建点信息
     * @param int $uid
     * @return array
     */
    public function getPointsInfo(int $uid)
    {
        $user = ShopAccount::where('uid', $uid)->first();
        $pointsSet = (new Setting())->getPointsSet();
        $pointsKey = array_column($pointsSet['level_info'], 'level_id');
        $pointsRules = array_combine($pointsKey, $pointsSet['level_info']);
        $pointBonus = $pointsSet['point_bonus'];
        $theRule = $pointsRules[$user->level];
        unset($pointsSet);
        unset($pointsKey);
        unset($pointsRules);
        $btreeModel = new Btree();
        $pnode = $btreeModel->where('uid', $uid)->first();
        if (!$pnode) {
            return [
                'seen_points' => 0,
                'seeing_points' => $theRule['level_points'],
                'point_bonus' => $pointBonus,
                'get_bonus' => 0,
                'pre_bonus' => $theRule['level_bonus']
            ];
        }
        $lowNodes = $btreeModel->where('btree_id', $pnode->btree_id)->where('level', '>', $pnode->level)
            ->where('level', '<', $pnode->level + $theRule['level_num'])
            ->select('uid', 'lchild', 'rchild')->get()->toArray();

        $children = $btreeModel->findLRZone($pnode->toArray(), $lowNodes);
        $seenPonints = count($children['lzone']) + count($children['rzone']);
        $seeingPoints = $theRule['level_points'] - $seenPonints;
        $getBonus = DB::table('money_report')->where('uid', $uid)->where('types', 1)->sum('amount');
        return [
            'seen_points' => $seenPonints,
            'seeing_points' => $seeingPoints,
            'point_bonus' => $pointBonus,
            'get_bonus' => $getBonus,
            'pre_bonus' => $theRule['level_bonus']
        ];
    }

    /**
     * 结算建点奖励
     * @param int $setUpUid
     */
    public function clearPointsBonus(int $setUpUid)
    {
        return true;   // 建点奖励被取消
        Log::info("{$setUpUid}被建点，发放奖励");
        $pointsSet = (new Setting())->getPointsSet();
        $pointsLayers = array_column($pointsSet['level_info'], 'level_num');
        $pointsKey = array_column($pointsSet['level_info'], 'level_id');
        $layersRules = array_combine($pointsKey, $pointsLayers);
        $pointBonus = $pointsSet['point_bonus'];
        unset($pointsSet);
        unset($pointsLayers);
        unset($pointsKey);
        $linkNodes = (new Btree())->findAllLinkNode($setUpUid);
        $insert = [];
        $now = time();
        foreach ($linkNodes as $link) {
            $canLayers = $layersRules[$link['level']];
            if ($canLayers >= $link['up_layers']) {  // 在建点层数内
                $insert[] = [
                    'uid' => $link['uid'],
                    'types' => 1,
                    'amount' => $pointBonus,
                    'status' => 1,
                    'remark' => '建点奖励',
                    'create_time' => $now,
                    'provider_uid' => $setUpUid
                ];
            }
        }
        DB::table('money_report')->insert($insert);

    }

    /*
     * 添加业绩
     *
     */
    public function addAchievement($uid, $money)
    {
        if (!$money) {
            Log::info("{$uid}输入业绩金额为0");
            return false;
        }
        $tree = (new Btree())->findAllLinkNode($uid);
        if (!$tree) return false;
        $updateData = array();
        $pv = (new Setting())->getTouchSet()['touch_pv'];
        $sucNumber = 0;
        (float)$addsale = (float)$pv * (float)$money;
        $Hierarchy = 0;
        DB::beginTransaction();
        $salesInsert = [];    // 业绩表数据插入数据初始化

        try {
            foreach ($tree as $k => $t) {
                if ($Hierarchy < 3) {
                    if ($k != 0) {
                        $treeuid = $tree[$k - 1]['uid'];  //$t子级的uid
                        $ableTouch = 0;
                        $data = array();
                        if ($treeuid == $t['lchild']) {
                            $ableTouch = $t['rsale'];
                            $data['lsale'] = bcadd((float)$t['lsale'],(float)$addsale,2);
                            $zone = 1;   // 左区业绩
                        } else if ($treeuid == $t['rchild']) {
                            $ableTouch = $t['lsale'];
                            $data['rsale'] = bcadd((float)$t['rsale'],(float)$addsale,2);
                            $zone = 2;   // 右区业绩
                        } else {
                            Log::info('btree数据错误:父级'.$t['uid'].',子级:'.$treeuid);
                            return false;
                        }
                        if ($ableTouch > 0) ++$Hierarchy;
                        $data['update_time'] = strtotime('now');
                        $updateData[$t['uid']] = $data;

                        $salesInsert[] = [
                            'uid' => $t['uid'],
                            'sale' => $addsale,
                            'zone' => $zone,
                            'pro_uid' => $uid,
                            'create_time' => time()
                        ];
                    }
                }
            }
            $count = count($updateData);
            // 向业绩表插入数据
            DB::table('sales')->insert($salesInsert);
            foreach ($updateData as $k_uid => $u) {
                $success = DB::table('btrees')->where(['uid' => $k_uid])->update($u);
                if ($success) {
                    $sucNumber = $sucNumber + 1;
                }
            }

        } catch (Exception $e) {
            $msg = $e->getMessage();
        }

        if ($count == $sucNumber) {
            DB::commit();
            return true;
        } else {
            DB::rollBack();
            return false;
        }
    }

    /*
     * 获取自己相反的兄弟是否有业绩
     * 自己的id；父级的数据
     * */
    public function getContrarySale($id, $pData)
    {
        if ($pData['lchild'] == $id) {
            return $pData['rsale'];
        } else if ($pData['rchild'] == $id) {
            return $pData['lsale'];
        }
    }

    /*
     * 量碰
      */
    public function AmountTouch(){

        $data = DB::table('btrees')->leftjoin('shop_accounts','btrees.uid','=','shop_accounts.uid')
            ->whereRaw('aixin_btrees.lsale>0 and aixin_btrees.rsale>0')
            ->selectRaw('aixin_shop_accounts.level as level,aixin_btrees.uid as uid,aixin_btrees.lsale as lsale,aixin_btrees.rsale as rsale,aixin_btrees.id as btrees_id')
            ->get();
        foreach($data as $d){
            $tolerance = 0;
            if($d->lsale>$d->rsale){
                $tolerance = $d->rsale;
            }else{
                $tolerance = $d->lsale;
            }
            $rate = (new Setting())->getCommissionRate($d->level);
            $achievement = bcmul((float)$rate,(float)$tolerance,2);
            $save = (new PeakReportService())->addIncome($d->uid,4,$achievement,null,'量碰收益');
            $update['lsale'] = bcsub((float)$d->lsale,(float)$tolerance,2);
            $update['rsale'] = bcsub((float)$d->rsale,(float)$tolerance,2);
            $update['update_time'] = strtotime('now');
            $success = DB::table('btrees')->where(['id'=>$d->btrees_id])->update($update);
            if($success){
                Log::info($d->uid.'用户量碰去除'.$tolerance);
            }else{
                Log::info('量碰失败btrees id.'.$d->btrees_id);
            }
        }
    }
}